import 'dart:async';

import 'package:audio_session/audio_session.dart';
import 'package:common/common.dart';
import 'package:just_audio/just_audio.dart';

//终止操作，播放下一个，上一个会被迫终止
typedef StopAction = void Function();

/// 回调播放器播放的时长和状态
/// @param playerId 播放器id
/// @param playState 播放状态
/// @param duration 播放时长

typedef OnDurationChanged = void Function(String playerId, bool playState, Duration duration);

/// 回调播放器播放的总时长和当前播放进度
/// @param toatlDuration 总时长
/// @param duration 播放时长
typedef OnDurationCurrentChanged = void Function(Duration toatlDuration, Duration duration);

///   播放器播放状态
typedef OnPlayerStateChanged = void Function(PlayerState state);

class JustAudioPlayer {
  JustAudioPlayer._();

  static final JustAudioPlayer instance = JustAudioPlayer._();
  AudioPlayer audioPlayer = AudioPlayer();

  StopAction? _stopAction;

  StreamSubscription? _subscription;

  OnPlayerStateChanged? onPlayerStateChanged; // 播放器状态回调
  Function? onStopCallback; // 停止播放语音回调
  OnDurationCurrentChanged? onDurationChanged; // 播放时长回调

  String playerId = ''; //

  /// [url] 播放地址 -  网络地址\下载文件地址\项目中的文件地址
  /// [id] 音频播放标识符
  /// [isAsset] 是否为项目资源
  /// [isLoop] 是否循环播放
  /// [speaker] 是否使用外部控制扬声器还是听筒播放
  /// [stopAction] 停止操作
  Future<void> play(
      {required String url,
      required String id,
      bool isAsset = false,
      bool isLoop = false,
      bool speaker = false,
      double volume = 1.0,
      required StopAction stopAction}) async {
    playerId = '';
    if (onStopCallback != null) {
      onStopCallback?.call();
    }
    await settingSpeaker(speaker: speaker);

    release();
    //回掉之前的停止操作
    _stopAction?.call();

    _stopAction = stopAction;
    audioPlayer = AudioPlayer();

    _subscription = audioPlayer.playerStateStream.listen((PlayerState playerState) {
      // logs('----    event- onPlayerStateChanged =  $playerState');
      //监听播放状态
      if (playerState.processingState == ProcessingState.completed) {
        _stopAction?.call();
        _stopAction = null;
        JustAudioPlayer.instance.playerId = '';
      }
      if (onPlayerStateChanged != null) {
        onPlayerStateChanged?.call(playerState);
      }
    });

    _subscription = audioPlayer.positionStream.listen((Duration duration) {
      Duration toatlDuration = audioPlayer.duration ?? Duration.zero;
      // logs('----    event- onDurationChanged =  $duration');
      if (onDurationChanged != null) {
        onDurationChanged?.call(toatlDuration, duration);
      }
    });

    playerId = id;

    if (isAsset) {
      await audioPlayer.setAsset(url);
      if (isLoop) {
        await audioPlayer.setLoopMode(LoopMode.all);
      }
    } else {
      if (url.startsWith('http')) {
        await audioPlayer.setUrl(url);
      } else {
        await audioPlayer.setFilePath(url);
      }
    }
    // await audioPlayer.setVolume(volume);
    await audioPlayer.play();
  }

  /// 设置扬声器还是听筒播放
  Future<void> settingSpeaker({required bool speaker}) async {
    if (speaker) {
      /// 设置扬声器还是听筒播放
      // int value = QSConfigRepo.getAudioPlayModel();
      bool isSpeakerphoneOn = true;
      // value == QSConfigRepo.audioPlayOutside;
      final session = await AudioSession.instance;
      if (isSpeakerphoneOn) {
        await session.configure(const AudioSessionConfiguration.speech());
      }
      // else {
      // await session.configure(const AudioSessionConfiguration(
      //   avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
      //   avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.allowBluetooth,
      //   avAudioSessionMode: AVAudioSessionMode.spokenAudio,
      //   avAudioSessionRouteSharingPolicy: AVAudioSessionRouteSharingPolicy.defaultPolicy,
      //   avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none,
      //   androidAudioAttributes: AndroidAudioAttributes(
      //     contentType: AndroidAudioContentType.speech,
      //     flags: AndroidAudioFlags.none,
      //     usage: AndroidAudioUsage.voiceCommunication,
      //   ),
      //   androidAudioFocusGainType: AndroidAudioFocusGainType.gain,
      //   androidWillPauseWhenDucked: true,
      // ));
      // }
    } else {
      try {
        final session = await AudioSession.instance;
        await session.configure(const AudioSessionConfiguration.speech());
      } catch (e) {
        logs('Error configuring audio session: $e');
      }
    }
  }

  void getCurrentPosition({required OnDurationChanged onDurationChanged}) async {
    if (audioPlayer.playing == true) {
      audioPlayer.positionStream.listen((Duration duration) {
        // logs('----    event- onDurationChanged =  $duration');
        onDurationChanged.call(JustAudioPlayer.instance.playerId.toString(), true, duration);
      });
    } else {
      onDurationChanged.call(JustAudioPlayer.instance.playerId.toString(), false, Duration.zero);
    }
  }

  bool isPlaying() {
    return audioPlayer.playing;
  }

  void stop() {
    audioPlayer.stop();
    JustAudioPlayer.instance.playerId = '';
  }

  void release() {
    JustAudioPlayer.instance.playerId = '';
    audioPlayer.dispose();
    _stopAction = null;
    _subscription?.cancel();
  }
}
